package com.zx1316.javasimpledoudizhu.server;

import javafx.application.Platform;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

//这个类处理服务端对客户端的连接
public class ListeningThread extends Thread {
    private final ServerSocket serverSocket;
    private final Server server;
    private final String password;

    public ListeningThread(Server server, ServerSocket serverSocket, String password) {
        this.server = server;
        this.serverSocket = serverSocket;
        this.password = password;
    }

    @Override
    public void run() {
        Socket socket;
        while (true) {
            try {
                socket = serverSocket.accept();
            } catch (IOException e) {
                e.printStackTrace();
                return;
            }
            try {
                BufferedReader r = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                PrintWriter w = new PrintWriter(socket.getOutputStream());
                String message = r.readLine();
                String[] str = message.split("@");
                if (str.length == 1 && !password.equals("") || str.length != 1 && !str[1].equals(password)) {
                    sendMessage(w, "WRONG");
                    socket.close();
                } else if (Server.getClients()[0] != null && Server.getClients()[1] != null && Server.getClients()[2] != null) {
                    sendMessage(w, "MAX");
                    socket.close();
                } else {
                    String name = str[0];
                    boolean flag = true;
                    int pos = 0;
                    if (!server.getGameThread().isInGame()) {
                        for (int i = 0; i < 3; i++) {
                            if (Server.getClients()[i] != null && Server.getClients()[i].getPlayerName().equals(name)) {
                                sendMessage(w, "SAME");
                                socket.close();
                                flag = false;
                                break;
                            }
                        }
                        if (flag) {
                            while (Server.getClients()[pos] != null) {
                                pos++;
                            }
                        }
                    } else {
                        for (pos = 0; pos < 3; pos++) {
                            if (server.getGameThread().getPlayerList()[pos].equals(name)) {
                                break;
                            }
                        }
                        if (pos == 3) {
                            sendMessage(w, "MAX");
                            socket.close();
                            flag = false;
                        }
                    }
                    if (flag) {
                        ClientThread client = new ClientThread(socket, name, server);
                        Server.getClients()[pos] = client;
                        client.start();
                        sendMessage(w, "RULES@" + server.getTotalRounds() + "@" + server.isHasTips() + "@" + server.isAllowDouble() + "@" + server.isAllowChat() + "@" + server.getGameThread().isInGame());
                        StringBuilder sb = new StringBuilder("NAME");
                        if (!server.getGameThread().isInGame()) {
                            for (int i = 0; i < 3; i++) {
                                sb.append("@");
                                if (Server.getClients()[i] != null) {
                                    sb.append(Server.getClients()[i].getPlayerName());
                                } else {
                                    sb.append(" ");
                                }
                            }
                            for (int i = 0; i < 3; i++) {
                                sendMessage(sb.toString(), i);
                            }
                            int finalPos = pos;
                            Platform.runLater(() -> {
                                String name1 = Server.getClients()[finalPos].getPlayerName();
                                switch (finalPos) {
                                    case 0 -> server.getController().name1.setText(name1);
                                    case 1 -> server.getController().name2.setText(name1);
                                    default -> server.getController().name3.setText(name1);
                                }
                            });
                        } else {
                            for (int i = 0; i < 3; i++) {
                                sb.append("@");
                                sb.append(server.getGameThread().getPlayerList()[i]);
                            }
                            sendMessage(w, sb.toString());
                            for (int i = 0; i < 3; i++) {
                                if (!client.equals(Server.getClients()[i])) {
                                    sendMessage("ADD@" + name, i);
                                }
                                if (Server.getClients()[i] == null) {
                                    sendMessage(w, "DELETE@" + server.getGameThread().getPlayerList()[i]);
                                }
                            }
                        }
                        for (int i = 0; i < 3; i++) {
                            if (Server.getClients()[i] != null && Server.getClients()[i].isReady()) {
                                sendMessage(w, "READY@" + Server.getClients()[i].getPlayerName());
                            }
                        }
                        if (server.getGameThread().isInGame()) {
                            sendMessage(w, "SCORE@" + server.getGameThread().getPlayerList()[0] + "@" + server.getGameThread().getScores()[0] + "@" + server.getGameThread().getPlayerList()[1] + "@" + server.getGameThread().getScores()[1] + "@" + server.getGameThread().getPlayerList()[2] + "@" + server.getGameThread().getScores()[2] + "@" + server.getGameThread().getRounds());
                            for (String send : server.getGameThread().getRecords().get(pos)) {
                                sendMessage(w, send);
                            }
                            if (server.getGameThread().isPause() && pos == server.getGameThread().getWaitingFor()) {
                                synchronized (server.getLock()) {
                                    server.getLock().notify();
                                }
                            }
                        }
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private void sendMessage(PrintWriter w, String message) {
        System.out.println("Server send " + message + " to new client");
        w.println(message);
        w.flush();
    }

    public void sendMessage(String message, int id) {
        System.out.println("Server send " + message + " to " + id + " name " + server.getGameThread().getPlayerList()[id]);
        if (Server.getClients()[id] != null) {
            Server.getClients()[id].getWriter().println(message);
            Server.getClients()[id].getWriter().flush();
        }
    }

    public ServerSocket getServerSocket() {
        return serverSocket;
    }
}
